#include "qqmusic.h"
#include "ui_qqmusic.h"

#include <QDebug>
QQMusic::QQMusic(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::QQMusic)
    ,currentPlayMusicIndex(-1)
{
    ui->setupUi(this);

    initUi();

    initSqlite();



    initPlayer();

    initMusicList(); //设置三个页面的类型 && 刷新三个页面里面的musicList
    connectSignalsAndSlots();  //链接所有的信号和槽


    currentPage = ui->localpage;
    currentPage->addMusicToPlaylist(musicList, playList); //处理程序启动的时候，从sqlite数据库中读数据，playList为空的情况
}



QQMusic::~QQMusic()
{
    delete ui;
}



void QQMusic::initUi()
{
    setWindowFlag(Qt::FramelessWindowHint);//设置窗口没有标题栏


    setWindowIcon(QIcon(":/image/tubiao.png"));  //设置在任务栏下方的图标

    ui->max->setEnabled(false);

    //设置系统托盘
    QSystemTrayIcon* trayIcon = new QSystemTrayIcon(this);
    trayIcon->setIcon(QIcon(":/image/tubiao.png"));
    trayIcon->show();
    //给托盘添加菜单
    QMenu* trayMenu = new QMenu(this);
    trayMenu->addAction("显示", this, &QWidget::showNormal);
    trayMenu->addAction("退出", this, &QQMusic::onQQmusicQuit);
    trayIcon->setContextMenu(trayMenu); //给系统托盘添加菜单栏


    //设置窗口背景透明
    setAttribute(Qt::WA_TranslucentBackground);
    //给窗口设置阴影效果 (如果父类widget设置填满，就可能不会有这个效果，也就是margin为0)
    QGraphicsDropShadowEffect* shadowEffect = new QGraphicsDropShadowEffect(this);
    shadowEffect->setOffset(0, 0); //设置阴影的偏移量为 (0, 0)，即阴影将与原图形项（或小部件）重合，不会有任何水平或垂直的偏移
    shadowEffect->setColor("#000000"); //黑色
    shadowEffect->setBlurRadius(10); //这个模糊的半径增大了以后，这个阴影也会重新刷新，后面的lrc歌词刷新出来的时候，所以要把这个阴影效果设置的小一点
    this->setGraphicsEffect(shadowEffect);


    //设置BtForm图标和 文本信息 和stackwidget中对应的pageid
    ui->rec->setIconAndText(":/image/rec.png", "推荐", 0);
    ui->audio->setIconAndText(":/image/radio.png", "电台", 1);
    ui->music->setIconAndText(":/image/music.png", "音乐馆", 2);
    ui->like->setIconAndText(":/image/like.png", "我喜欢", 3);
    ui->local->setIconAndText(":/image/local.png", "本地下载", 4);
    ui->recent->setIconAndText(":/image/recent.png", "最近播放", 5);

    //本地下载BtForm动画默认显示
    //ui->local->showAnimal();

    srand(time(NULL));// 设置随机数的种子， 给random_shuffle用
    //randomPiction();
    ui->recMusicBox->initRecBoxUi(randomPiction(), 1);
    ui->supplyMusicBox->initRecBoxUi(randomPiction(), 2);

    //设置CommonPage的信息

    ui->likepage->setCommonPageUI("我喜欢", ":/image/ilikebg.png");

    ui->localpage->setCommonPageUI("本地音乐", ":/image/localbg.png");

    ui->recentpage->setCommonPageUI("最近播放", ":/image/recentbg.png");

    volumeTool = new VolumeTool(this);
    //volumeTool->hide();

    //播放控制区按钮图标的设定
    ui->Play->setIcon(QIcon(":/image/play3.png"));
    ui->playMode->setIcon(QIcon(":/image/shuffle_2.png"));

    //将localPage设置为当前页面
    ui->stackedWidget->setCurrentIndex(4);
    currentPage = ui->localpage;
    updateBtformAnimal();

    //实例话LrcWord对象, 这个歌词按钮点击以后，应该让歌词窗口慢慢上移动，最后和QQMusic主窗口重叠
    //当点击歌词窗口的左上角按钮时，歌词应该慢慢下移，最后消失(当动画效果结束以后，歌词窗口隐藏，hide())
    //所以窗口上移动的动画，需要在QQmsuic中实现，下移的时候需要在lrcPage中实现
    lrcPage = new LrcPage(this);
    lrcPage->setGeometry(10, 10, lrcPage->width(), lrcPage->height());
    lrcPage->hide();

    //初始化上移动画对象
    lrcPageAnimal = new QPropertyAnimation(lrcPage, "geometry", this);
    lrcPageAnimal->setDuration(250); //设置完成这一个动画的持续时长
    lrcPageAnimal->setStartValue(QRect(10, 10 + lrcPage->height(), lrcPage->width(), lrcPage->height()));
    lrcPageAnimal->setEndValue(QRect(10, 10, lrcPage->width(), lrcPage->height()));
}



void QQMusic::mouseMoveEvent(QMouseEvent *event)
{
    if(Qt::LeftButton == event->buttons()&& isDrag)
    {
      //  qDebug() << event->globalPos();
        move(event->globalPos() - dragPosition);  //move的作用是移动窗口
        return;
    }

    QWidget::mouseMoveEvent(event);  //否则交给父窗口去处理
}


void QQMusic::mousePressEvent(QMouseEvent *event)
{
    if(Qt::LeftButton == event->button())
    {
        isDrag = true;
        //获取鼠标相当于屏幕左上角的全局坐标
       // qDebug() << event->globalPos();
        dragPosition =  event->globalPos() - geometry().topLeft();
        return;
    }

    QWidget::mousePressEvent(event);
}



void QQMusic::connectSignalsAndSlots()
{
    //连接一个类和另一个类的两个函数 （信号和槽）
    connect(ui->rec, &BtForm::btClick, this, &QQMusic::onBtFormClick);
    connect(ui->audio, &BtForm::btClick, this, &QQMusic::onBtFormClick);
    connect(ui->music, &BtForm::btClick, this, &QQMusic::onBtFormClick);
    connect(ui->like, &BtForm::btClick, this, &QQMusic::onBtFormClick);
    connect(ui->local, &BtForm::btClick, this, &QQMusic::onBtFormClick);
    connect(ui->recent, &BtForm::btClick, this, &QQMusic::onBtFormClick);

    //收藏或者不收藏的处理，updateLikeMusic信号触发的时机：当点击listitemBox里面的likebtn以后，触发onLikeBtnClicked
    //然后他发送setIsLike信号给它的父控件CommonPage里面的lambda表达式。然后触发整个updateLikeMusic信号
    //然后通过QQMusic的musicList找到对应的musicid，吧like属性设置进去，然后三个Page页面调用reFresh函数刷新页面
    //而reFresh函数的操作流程是，先把addMusicToMusicPage(musicList），通过musiclist把所有歌曲设置到对应page的pageoflist
    connect(ui->localpage, &CommonPage::updateLikeMusic, this, &QQMusic::onUpdateLikeMusicAndPage);
    connect(ui->likepage, &CommonPage::updateLikeMusic, this, &QQMusic::onUpdateLikeMusicAndPage);
    connect(ui->recentpage, &CommonPage::updateLikeMusic, this, &QQMusic::onUpdateLikeMusicAndPage);


    //播放控制区的信号和槽函数关联
    connect(ui->Play, &QPushButton::clicked, this, &QQMusic::onPlayMusic);
    //上一首的槽函数
    connect(ui->playUp, &QPushButton::clicked, this, &QQMusic::onPlayUpClicked);
    //下一首的槽函数
    connect(ui->playDown, &QPushButton::clicked, this, &QQMusic::onPlayDownClicked);
     //当播放模式发生改变的时候 随机播放-->顺序播放-->单曲循环
    connect(ui->playMode, &QPushButton::clicked, this, &QQMusic::onPlaybackModeClicked);


    //likePage, localPage, recentPage的播放所有按钮点击之后的槽函数
    connect(ui->likepage, &CommonPage::PlayAll, this, &QQMusic::onPlayAll);
    connect(ui->localpage, &CommonPage::PlayAll, this, &QQMusic::onPlayAll);
    connect(ui->recentpage, &CommonPage::PlayAll, this, &QQMusic::onPlayAll);


    //双击三个page页面中listItemBox双击后播放音乐
    connect(ui->likepage, &CommonPage::playMusicByIndex, this, &QQMusic::playMusicByIndex);
    connect(ui->localpage, &CommonPage::playMusicByIndex, this, &QQMusic::playMusicByIndex);
    connect(ui->recentpage, &CommonPage::playMusicByIndex, this, &QQMusic::playMusicByIndex);

    //当playList中播放源发生变化时, 需要记录当前的下标，因为这个下标与对应的page页面的musicofpage的下标是一致的
    //可以用来获得路径啥的
    connect(playList, &QMediaPlaylist::currentIndexChanged, this, &QQMusic::onCurrentIndexChanged);

    //处理的是静音
    connect(volumeTool, &VolumeTool::setMusicMuted, this, &QQMusic::setPlayerMuted);

    //处理的是设置音量大小
    connect(volumeTool, &VolumeTool::setMusicVolume, this, &QQMusic::setPlayerVolume);


    //关联QMediaPlayer::durationChanged当媒体文件的总时长（即媒体的持续时间）发生变化时，该信号会被触发
    connect(player, &QMediaPlayer::durationChanged, this, &QQMusic::onDurationChanged);

    //关联QMediaPlayer::positionChanged  当媒体播放的当前播放位置发生变化时，该信号会被触发。也就是说，每当播放进度发生变化时，它会发出信号
    connect(player, &QMediaPlayer::positionChanged, this, &QQMusic::onPositionChanged);


    //关联MusicSlider::setMusicSliderPostion
    connect(ui->progressbar, &MusicSlider::setMusicSliderPostion, this, &QQMusic::onMusicSliderChanged);



    //歌词按钮点击，显示LRC歌词
    connect(ui->lrcBtn, &QPushButton::clicked, this, &QQMusic::onLrcWordClicked);
}


//该函数是用来设置推荐页面recboxitem的图片和文本的
QJsonArray QQMusic::randomPiction()
{
    QVector<QString> vecImageName;
    vecImageName << "001.png" << "015.png" << "003.png" << "004.png" << "005.png" << "006.png" << "007.png"
             << "008.png" << "009.png" << "010.png" << "011.png" << "012.png"<< "013.png" << "014.png"
             << "016.png" << "017.png" << "018.png" << "019.png" << "020.png" << "021.png" << "022.png"
             << "023.png" << "024.png" << "025.png" << "026.png" << "027.png" << "028.png" << "029.png"
             << "030.png" << "031.png" << "032.png" << "033.png" << "034.png" << "035.png" << "036.png"
             << "037.png" << "038.png" << "039.png" << "040.png" ;



    std::random_shuffle(vecImageName.begin(), vecImageName.end()) ; //把容器中的元素给打散。

//    for(auto& e: vecImageName)
//    {
//        qDebug() << e << "  ";
//    }

    QJsonArray objArray;
    for(int i = 0; i < vecImageName.size(); i++)
    {
        //每张图片的路径是 :/image/rec/ + vecImageName[i]
        //text: "推荐-001" "推荐-002" ....

        QJsonObject obj;
        obj.insert("path", ":/image/rec/" + vecImageName[i]);
        //arg()， 第一个参数是值，第二个是占位多少， 第三个是多少进制的数据,第4个是补什么东西
        QString strText = QString("推荐-%1").arg(i, 3, 10, QChar('0'));
        obj.insert("text", strText);

        objArray.append(obj);
//        qDebug() << obj.value("path").toString();
//        qDebug() << obj.value("text").toString();
    }

    return objArray;  //把图片的路径和推荐信息可以交给recbox去使用
}


//点击关闭按钮的时候，程序不应该是直接退出，而是
void QQMusic::on_quit_clicked()
{
    hide(); //关闭当前窗口
}


void QQMusic::onBtFormClick(int pageid)
{

    //清除之前btForm按钮的颜色背景
    //获取所有的BtForm按钮,然后pageid又标识的是QList中的一个BtForm
    QList<BtForm*> btFormList  = this->findChildren<BtForm*>();
    for(auto btForm: btFormList)
    {
        if(btForm->getPageId() != pageid)
        {
             btForm->clearBackGround();
        }
    }

    ui->stackedWidget->setCurrentIndex(pageid);

    isDrag = false;
}



void QQMusic::on_volume_clicked()
{
    // 1，获取ui界面的volume的左上角的坐标,并转换为屏幕的全局坐标,调用mapToGlobal（传参QPoint(0,0)）
    QPoint point =  ui->volume->mapToGlobal(QPoint(0, 0));

    //2，计算volumeTool需要移动到的位置， ui->volume的左上方
    QPoint volumeLeftTop = point - QPoint(volumeTool->width() / 2, volumeTool->height());

    volumeLeftTop.setX(volumeLeftTop.x() +15);
    volumeLeftTop.setY(volumeLeftTop.y() +30);

    //3， 移动volumeTool
    volumeTool->move(volumeLeftTop);

    //4，显示窗口
    volumeTool->show();

}


void QQMusic::on_addLocal_clicked()
{
    QFileDialog fileDialog(this);

    fileDialog.setWindowTitle("添加本地下载音乐");

    QString projectPath = QDir::currentPath();
    QDir dir(projectPath);
    dir.cdUp();  //进入上一层的目录
  //  qDebug() << dir.path();
    QString path = dir.path();
    path += "/QQMusic/musics/";
    qDebug() << path;
    fileDialog.setDirectory(path);
    fileDialog.setFileMode(QFileDialog::ExistingFiles); // 设置一次可以选择多个文件
    fileDialog.setNameFilter("代码文件(*.h *.c *.hpp *.cpp)");  //通过文件后缀去过滤普通文件

    //fileDialog.setNameFilter("图片文件(*.png *.bmp *.jpg)");
    // qDebug() << projectPath;
    //fileDialog.setDirectory("")


    //通过文件的MIME类型来过滤
    QStringList mimeTypeFileters;
    mimeTypeFileters  << "application/octet-stream"; // application/octet-stream 通过二进制流的形式去过滤
    fileDialog.setMimeTypeFilters(mimeTypeFileters);

    if(QDialog::Accepted == fileDialog.exec())//模态对话框，也就是这个文件窗口显示的时候，其他页面不能点击
    {
        //选择的是打开
       // qDebug() << "打开";

        //获取选中的文件即可
        QList<QUrl> fileUrls = fileDialog.selectedUrls();
        qDebug() << "--------------------------------------";
        qDebug() << fileUrls;
        qDebug() << "--------------------------------------";
        // fileUrls :内部存放的是刚刚选中的文件的url路径
        // 需要将文件信息添加到本地下载的页面 其中包括了歌曲名称， 歌曲作者， 歌曲专辑， 歌曲总时间
        // 封装成一个 Music类 ，描述歌曲音乐
        // 每一首音乐都对应一个Music对象，程序中的Music对象比较多，因此Music对象也需要管理，再次封装一个类MusicList(音乐列表)
        // 然后将所有音乐添加到音乐列表中，MusicList
       musicList.addMusicsByUrl(fileUrls); //->将歌曲文件向musicList文件中时需要去重过滤

       // 将歌曲信息更新到CommonPage页面的ListWidget中
       // 将CommonPage
       // 将CommonPage切换到本地下载的页面
       ui->stackedWidget->setCurrentIndex(4);

       ui->localpage->reFresh(musicList);
        // /D:/code_2024/QQMusic/musics/笨小孩(国) - 刘德华.mp3
       ui->localpage->addMusicToPlaylist(musicList, playList);  //添加音乐到playList中
    }
    else
    {
        //选择的是取消
        //qDebug() << "取消";
    }
}


//只要点击了我喜欢，就要更新这三个页面
void QQMusic::onUpdateLikeMusicAndPage(bool isLike, const QString &musicId)
{
    //1,修改状态
    auto it = musicList.findMusicByMusicId(musicId);
    if(it != musicList.end())
    {
        it->setIsLike(isLike);
    }

    ui->likepage->reFresh(musicList);
    ui->localpage->reFresh(musicList);
    ui->recentpage->reFresh(musicList);
}


///////////////////////////////////////////////////////////////////
// 播放控制说明
// 播放和暂停
// 播放控制区域
// 播放音乐的流程：
//可以借助QMediaPlaylist去播放多首音乐，
void QQMusic::onPlayMusic()
{
    qDebug() << "onPlayMusic";
//    //但是QMeidiaPlayer只能播放一首音乐
//    //1,添加媒体源。//设置媒体源的路径，因为QMediaContent里面有一个url的构造函数
//    player->setMedia(musicList.begin()->getMusicQurl());

//    //2,播放
//    player->play();

    if(player->state() == QMediaPlayer::PlayingState)
    {
        //播放中点击，需要暂停
        player->pause();
     //   ui->Play->setIcon(QIcon(":/image/play3.png"));
    }
    else if(QMediaPlayer::PausedState == player->state())
    {
        qDebug() << "PausedState";
        //暂停状态点击按钮，需要继续播放
        player->play();
       // ui->Play->setIcon(QIcon(":/image/play_on.png"));
    }
    else if(QMediaPlayer::StoppedState == player->state())
    {
         qDebug() << "StoppedState";
        //刚开始默认为停止状态，当点击播放按钮时
        player->play();
      //  ui->Play->setIcon(QIcon(":/image/play_on.png"));
    }
    else
    {
        qDebug() << player->errorString();
    }
}


//在QQMusic中，有一个musicList的对象，内部管理了所以的歌曲，不能将musicList中所有的音乐添加到playlist
//因为musicList保存了所有的歌曲，而播放音乐的时候，是按照likepage,localpage,recentpage来播放的
//应该将具体页面中的歌曲设置到playlist中，所以逻辑是：  addMusicToPlaylist只能在CommongPage类中定义
//因为对应的page保存了具体自己的歌曲
void QQMusic::initPlayer()
{
    //初始化媒体播放相关的类
    player = new QMediaPlayer(this);
    playList = new QMediaPlaylist(this);

    //设置默认的播放模式
    playList->setPlaybackMode(QMediaPlaylist::Random);


    //将播放列表设置到媒体对象中
    player->setPlaylist(playList);

    //设置默认的音量大小
    player->setVolume(20);

    //    ui->localpage->addMusicToPlaylist(musicList, pla);
    //关联QMeidaPlayer的信号，播放器的装填，例如暂停，开始，继续
    connect(player, &QMediaPlayer::stateChanged, this, &QQMusic::onPlayerStateChanged); //切换按钮的图片

    //关联QMediaPlayer::metaDataAvailableChanged 信号，表示媒体的元数据是否可用发生变化
    //当媒体文件开始播放时，可能会从文件中提取元数据，发射这个信号可以帮助你判断何时可以显示或更新播放信息
    connect(player, &QMediaPlayer::metaDataAvailableChanged, this, &QQMusic::onMetaDataAvailableChanged);
}


void QQMusic::onPlayerStateChanged()
{
    if(player->state() == QMediaPlayer::PlayingState)
    {
        ui->Play->setIcon(QIcon(":/image/play_on.png"));
    }
    else
    {
        ui->Play->setIcon(QIcon(":/image/play3.png"));
    }
}


void QQMusic::onPlayUpClicked()
{
    playList->next();
}


void QQMusic::onPlayDownClicked()
{
    playList->previous();
}



//播放模式切换功能  QMediaPlaylist
//在模式切换按钮槽函数中,获取当前playList所处的播放模式
//列表循环---->随机播放
//随机播放---->单曲循环
//单曲循环---->列表循环
//如果不是以上三种，则认为暂不支持的模式

void QQMusic::onPlaybackModeClicked()
{
    //根据当前播放模式，切换到下一个播放模式
    //设置ToolTip模式
    //列表循环--->随机播放--->单曲循环
    //当状态发生改变的时候，还需要修改按钮上的图标
    if(playList->playbackMode() == QMediaPlaylist::Loop)
    {
        //随机播放
        playList->setPlaybackMode(QMediaPlaylist::Random);
        ui->playMode->setToolTip("随机播放");
        ui->playMode->setIcon(QIcon(":/image/list_play.png"));
    }
    else if(playList->playbackMode() == QMediaPlaylist::Random)
    {
        //单曲循环
        playList->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
        ui->playMode->setToolTip("单曲循环");
        ui->playMode->setIcon(QIcon(":/image/single_play.png"));
    }
    else if(playList->playbackMode() == QMediaPlaylist::CurrentItemInLoop)
    {
        //列表循环
        playList->setPlaybackMode(QMediaPlaylist::Loop);
        ui->playMode->setToolTip("列表循环");
        ui->playMode->setIcon(QIcon(":/image/shuffle.png"));
    }
    else
    {
        //暂不支持
        qDebug() << "暂不支持该模式";
    }
}


void QQMusic::onCurrentIndexChanged(int index)
{
    currentPlayMusicIndex = index;
    //由于CommonPage页面中的歌曲和正在播放的播放列表中的歌曲的先后次序是相同的
    //知道歌曲在playlist中的索引之后，直接到CommonPage中获取。
    //其中playlist中的歌曲就是根据CommonPage中的musicOfPage中获取
    QString musicId = currentPage->getMusicIdByIndex(index);

    auto it = musicList.findMusicByMusicId(musicId);
    if(it != musicList.end())
    {
        it->setIsHistory(true);
    }

    ui->recentpage->reFresh(musicList);
}



void QQMusic::onPlayAll(PageType pagetype)
{
   CommonPage* page = ui->localpage;
   switch (pagetype)
   {
   case PageType::LIKE_Page:
       page = ui->likepage;
       break;
   case PageType::LOCAL_Page:
       page = ui->localpage;
       break;
   case PageType::HISTORY_Page:
       page = ui->recentpage;
       break;
   default:
        qDebug() << "暂不支持的页面";
   }


   //page中记录的就是要播放的页面
   playAllMusicOfCommonPage(page, 0);
}


//这个page就是对应的 like_page, recentpage, local_page
void QQMusic::playAllMusicOfCommonPage(CommonPage *page, int index)
{
    currentPage = page; //确定播放的是那个页面的歌曲
    updateBtformAnimal();

    //清空之前playList中的歌曲
    playList->clear();

    //添加当前要播放的page页面
    page->addMusicToPlaylist(musicList, playList); //里面会继续对musicList进行过滤的

    //播放从第0首开始播放
    playList->setCurrentIndex(index);

    player->play(); //开始播放
}


void QQMusic::playMusicByIndex(CommonPage *page, int index)
{
    playAllMusicOfCommonPage(page, index);
}


//volumnTool 中对应的静音槽函数
void QQMusic::setPlayerMuted(bool isMuted)
{
    player->setMuted(isMuted);
}


void QQMusic::setPlayerVolume(int volume)
{
    player->setVolume(volume);
}


//歌曲一共的时间
void QQMusic::onDurationChanged(qint64 duration)
{
    totalTime = duration;
    //duration是歌曲的总时长,单位为毫秒,转换为  min:sec
//    分:duration / 1000 / 60;
//    秒:duration / 1000 % 60

    ui->totaltime->setText(QString("%1:%2").arg(duration/1000/60, 2, 10, QChar('0'))
                                           .arg(duration / 1000 % 60, 2, 10, QChar('0')));
}


//当前的总播放时间
void QQMusic::onPositionChanged(qint64 postion)
{
    ui->current_time->setText(QString("%1:%2").arg(postion/1000/60, 2, 10, QChar('0'))
                              .arg(postion / 1000 % 60, 2, 10, QChar('0')));

    //更新进度条的位置
    ui->progressbar->setStep(postion / (float)totalTime);


    //在这里同步显示歌词，
    if(currentPlayMusicIndex >= 0)
        lrcPage->showLrcWordLine(postion);
}



void QQMusic::onMusicSliderChanged(float ration)
{
    qint64 duration = totalTime * ration;
    ui->current_time->setText(QString("%1:%2").arg(duration/ 1000 / 60, 2, 10, QChar('0'))
                                              .arg(duration / 1000 % 60, 2, 10, QChar('0')));

    //时间修改了以后，播放时间也需要修改
    player->setPosition(duration);
}


//当player的媒体源发生变化的时候
void QQMusic::onMetaDataAvailableChanged(bool available)
{
    //歌曲名称，歌曲作者直接到Music对象中获取
    //这个时候需要知道媒体源在播放列表中的索引
    QString musicId = currentPage->getMusicIdByIndex(currentPlayMusicIndex);
    auto it = musicList.findMusicByMusicId(musicId);
    QString musicName = "未知歌曲";
    QString musicSinger = "未知歌手";
    if(it != musicList.end())
    {
        qDebug() << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
        //获取歌曲的名称
        musicName = it->getMusicName();
        musicSinger = it->getMusicSinger();
    }

    ui->musicName->setText(musicName);
    ui->musicSinger->setText(musicSinger);


    //获取封面图，通过元数据来获取，每一首音乐是自带封面图片的。
    QVariant coverimage = player->metaData("ThumbnailImage");
    //QVarint --里面可以检测是否是未知的类型
    if(coverimage.isValid())
    {
        QImage image = coverimage.value<QImage>();

        //更新到界面中
        ui->musicCover->setPixmap(QPixmap::fromImage(image));

        ui->musicCover->setScaledContents(true); //如果没有填充满QLable，可以设置为自动伸缩。

        currentPage->setMusicImage(QPixmap::fromImage(image));
    }
    else
    {
        qDebug() << "歌曲没有封面图";
        QString path = ":/image/rec/001.png";
        ui->musicCover->setPixmap(path);
        ui->musicCover->setScaledContents(true); //如果没有填充满QLable，可以设置为自动伸缩。

        currentPage->setMusicImage(path);
    }


    //解析歌曲的LRC歌词。
    if(it != musicList.end())
    {
        //获取lrc文件的路径
        QString lrcPath = it->getLrcFilePath();

        //解析lrc文件的路径,打开文件，按行读取文件中的每一行歌词时间 + 歌词
        //文件中的一行文本显示的格式：
        //[0:17.94]xxxxxxxxxxxx
        //[0:33.600.00]xxxxxxxxxxxxxxxx
        //找 ']'之前为时间， ']'之后为歌词文本
        //假设读取到的一行歌词为Lrc Word
        lrcPage->parseLrcFile(lrcPath);
    }
}


void QQMusic::onLrcWordClicked()
{
    qDebug() << "onLrcWordClicked";
    lrcPage->show();
    lrcPageAnimal->start();
}



void QQMusic::initSqlite()
{
    //进行数据库驱动加载
     sqlite = QSqlDatabase::addDatabase("QSQLITE");

    //设置数据库名称
    sqlite.setDatabaseName("QQMusic.db");

    //打开
    if(!sqlite.open())
    {
        QMessageBox::critical(this, "QQMusic", "数据库打开失败!!!");
        return;
    }

    qDebug() << "QQMusic数据库链接成功";

    //创建表
    QString sql = "create table if not exists MusicInfo(\
                   id integer primary key autoincrement,\
                   musicId varchar(50),\
                   musicName varchar(200),\
                   musicSinger varchar(200),\
                   albumName varchar(50),\
                   musicUrl varchar(256),\
                   duration bigint,\
                   isLike integer,\
                   isHistory integer)";

    QSqlQuery query;
    if(!query.exec(sql))
    {
        QMessageBox::critical(this, "QQMusic", "初始化错误!!");
        return;
    }

    qDebug() << "创建数据库 和 数据表 成功";
}



void QQMusic::initMusicList()
{
    musicList.readFromDB();
    ui->likepage->setMusicListType(PageType::LIKE_Page);
    ui->likepage->reFresh(musicList);

    ui->localpage->setMusicListType(PageType::LOCAL_Page);
    ui->localpage->reFresh(musicList);

    ui->recentpage->setMusicListType(PageType::HISTORY_Page);
    ui->recentpage->reFresh(musicList);

//    currentPage = ui->localpage;
//    currentPage->addMusicToPlaylist(musicList, playList);
}







//更换界面的皮肤
void QQMusic::on_skin_clicked()
{
    //类似： 给窗口更换背景颜色 或者 更换背景图片
    QMessageBox::information(this, "温馨提示", "换肤功能正在紧急支持中....");
}







//最小化--
void QQMusic::on_min_clicked()
{
    showMinimized(); //让窗口最小化显示
}







void QQMusic::on_max_clicked()
{
    showMaximized();
}

void QQMusic::updateBtformAnimal()
{
    //通过currentPage在stackWidget中的索引
    int index = ui->stackedWidget->indexOf(currentPage);
    if(-1 == index)
    {
        qDebug() << "该页面不存在";
        return;
    }

    QList<BtForm*> btForms = this->findChildren<BtForm*>();
    for(auto btForm : btForms)
    {
        if(btForm->getPageId() == index)
        {
            //将currentPage与对应的btForm找到了
            btForm->showAnimal(true);
        }
        else
        {
            btForm->showAnimal(false);
        }
    }
}

void QQMusic::onQQmusicQuit()
{
    //歌曲信息写入数据库
    musicList.writeToMusicDB();

    //断开SQLite的链接
    sqlite.close();

    close();
}







